/*
判断Rpc请求函数名称、函数参数是否合法，如果合法，调用相应的回调函数
*/

#pragma once

#include "../Common/Net.hpp"
#include "../Common/Message.hpp"

#include <functional>

namespace RpcModule
{
    namespace ServerModule
    {
        enum class RpcType
        {
            BOOL = 0, // 布尔类型
            INTEGRAL, // 整形
            NUMERIC,  // 浮点型
            STRING,   // 字符串
            ARRAY,    // 数组
            OBJECT    // 对象(Json)
        };

        // 服务描述类 -- 提供了参数的判断
        class ServiceDescribe
        {
        public:
            using ptr = std::shared_ptr<ServiceDescribe>;
            using ServiceCallBack = std::function<void(const Json::Value &, Json::Value &)>;
            using ParamsDescribe = std::pair<std::string, RpcType>;
            // 参数校验逻辑实现
            bool ParamCheck(const Json::Value &params) {}

        private:
            std::string _method_name;                 // 方法名称
            ServiceCallBack _callback;                // 回调函数
            std::vector<ParamsDescribe> _params_desc; // 参数描述
            RpcType _return_type;                     // 返回类型描述
        };
        class ServiceDescribeFactory
        {
        public:
            static ServiceDescribe::ptr Create() {}
        };

        // 服务管理类 -- 对于大量的服务，需要进行管理
        class ServiceManager
        {
        public:
            using ptr = std::shared_ptr<ServiceManager>;
            // 增加服务
            ServiceDescribe::ptr Create() {}
            // 查询服务
            ServiceDescribe::ptr Select() {}
            // 删除服务
            void Remove() {} 
        private:
            std::mutex _mutex;
            std::unordered_map<std::string, ServiceDescribe::ptr> _services;
        };

        class RpcRouter
        {
        public:
            using ptr = std::shared_ptr<RpcRouter>; 
            // 进行服务的注册
            void RegisterMethod(const ServiceDescribe::ptr& service) {}
            // Rpc调用的回调函数
            void OnRpcRequest(const BaseConnection::ptr& conn, RpcRequest::ptr& request)
            {
                // 1. 查询请求的方法名称，判断服务端是否能提供该方法的服务
                // 2. 进行参数校验
                // 3. 调用相应的业务处理回调函数
                // 4. 处理完毕得到结果，序列化之后，发送给客户端
            }
        private:
            ServiceManager::ptr _service_manager;
        };
    }
}